package com.zq.im;

import android.content.Context;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.gyf.immersionbar.ImmersionBar;
import com.gyf.immersionbar.OnKeyboardListener;
import com.zq.im.adapter.ChatMessageAdapter;
import com.zq.im.api.MessageApi;
import com.zq.im.bean.BaseModel;
import com.zq.im.bean.param.UnReceivedMessageIds;
import com.zq.im.modle.ChatMessage;
import com.zq.im.modle.ChatMsg;
import com.zq.im.modle.DataContent;
import com.zq.im.modle.MsgActionEnum;
import com.zq.im.modle.UnReceivedMessage;
import com.zq.im.retrofit.BaseCallBack;
import com.zq.im.retrofit.RetrofitManager;
import com.zq.im.room.dao.MessageDao;
import com.zq.im.room.database.MyDataBase;
import com.zq.im.room.entity.Message;
import com.zq.im.utils.SharePreferenceUtils;
import com.zq.im.utils.Util;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Call;


public class MessageActivity extends BaseActivity implements View.OnClickListener {

    private static final String TAG = "MessageActivity";
    @BindView(R.id.et_content)
    EditText mEditText;
    @BindView(R.id.chatmsg_listView)
    ListView listView;
    @BindView(R.id.btn_send)
    Button mBtnSend;
    private List<ChatMessage> chatMessageList = new ArrayList<>();//消息列表
    private ChatMessageAdapter mChatMessageAdapter;

    /**
     * 和我聊天的这个人的用户id,
     */
    private String mTalkerId; //和我聊天的这个人的id

    private String mNickName;
    private Context mContext;

    @BindView(R.id.name)
    TextView name;
    private String mMyUserId;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_message;
    }

    @Override
    protected void initImmersionBar() {
        ImmersionBar.with(this)
                .titleBarMarginTop(R.id.title_bar)
                .barColor(R.color.message_activity_title_bar_color)
                .keyboardEnable(true)
                .setOnKeyboardListener(new OnKeyboardListener() {
                    @Override
                    public void onKeyboardChange(boolean isPopup, int keyboardHeight) {
                        listView.setSelection(chatMessageList.size());
                    }
                })
                .statusBarDarkFont(true)
                .init();
    }

    @Override
    public void initView() {

        mChatMessageAdapter = new ChatMessageAdapter(mContext, chatMessageList);
        listView.setAdapter(mChatMessageAdapter);
        mBtnSend.setOnClickListener(this);
        //监听输入框的变化
        mEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (mEditText.getText().toString().length() > 0) {
                    mBtnSend.setVisibility(View.VISIBLE);
                } else {
                    mBtnSend.setVisibility(View.GONE);
                }
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }

    @Override
    protected void initData() {
        super.initData();
        mMyUserId = SharePreferenceUtils.getString("userId");
        Intent intent = getIntent();
        mTalkerId = intent.getStringExtra("receiverId");
        mNickName = intent.getStringExtra("nickName");
        name.setText(mNickName);
        mContext = MessageActivity.this;

        //查出历史聊天数据
        MessageDao messageDao = MyDataBase.getInstance(this).getMessageDao();
        Disposable subscribe = messageDao.getMessage(SharePreferenceUtils.getString("userId"), mTalkerId)
                .map((Function<List<Message>, List<ChatMessage>>) messages -> {
                    String userId = SharePreferenceUtils.getString("userId");
                    ArrayList<ChatMessage> chatMessages = new ArrayList<>();
                    for (Message message : messages) {
                        ChatMessage chatMessage = new ChatMessage();
                        chatMessage.setContent(message.getMsg());
                        chatMessage.setTime(message.getCreateTime());
                        if (userId.equals(message.getSendUserId())) {
                            chatMessage.setIsMeSend(1);
                        } else {
                            chatMessage.setIsMeSend(0);
                        }
                        chatMessage.setIsRead(1);
                        chatMessages.add(chatMessage);
                    }
                    return chatMessages;
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<List<ChatMessage>>() {
                    @Override
                    public void accept(List<ChatMessage> chatMessages) throws Exception {
                        chatMessageList.clear();
                        chatMessageList.addAll(chatMessages);
                        mChatMessageAdapter.setChatMessageList(chatMessageList);
                        mChatMessageAdapter.notifyDataSetChanged();
                        listView.setSelection(chatMessageList.size());
                    }
                });


        //从服务端获取因为离线未收到的消息
        MessageApi messageApi = RetrofitManager.getRetrofit().create(MessageApi.class);
        Call<BaseModel<List<UnReceivedMessage>>> unReceivedMessage =
                messageApi.getUnReceivedMessage(SharePreferenceUtils.getString("userId"));
        unReceivedMessage.enqueue(new BaseCallBack<List<UnReceivedMessage>>() {
            @Override
            public void onSuccess(List<UnReceivedMessage> list) {
                ArrayList<ChatMessage> chatMessages = new ArrayList<>();
                UnReceivedMessageIds unReceivedMessageIds = new UnReceivedMessageIds();
                //转变成 chatMessage
                for (UnReceivedMessage unReceivedMessage : list) {
                    ChatMessage chatMessage = new ChatMessage();
                    chatMessage.setContent(unReceivedMessage.getMsg());
                    chatMessage.setIsMeSend(0);
                    chatMessage.setIsRead(1);
                    chatMessage.setTime(unReceivedMessage.getCreateTime());
                    chatMessages.add(chatMessage);
                    unReceivedMessageIds.add(unReceivedMessage.getId());
                }
                //1.告诉后台消息已经被读取
                EventBus.getDefault().post(unReceivedMessageIds);

                //拿到未读消息之后,存到本地数据库
                //转变数据结构
                ArrayList<Message> messages = new ArrayList<>();
                for (UnReceivedMessage unReceivedMessage : list) {
                    Message message = new Message(unReceivedMessage.getId(), mTalkerId, mMyUserId, unReceivedMessage.getMsg(), unReceivedMessage.getCreateTime());
                    messages.add(message);
                }
                insertAll(messages);
            }

            @Override
            public void onFailure(Throwable t) {

            }
        });


    }

    void insertAll(List<Message> messages) {
        MessageDao messageDao = MyDataBase.getInstance(this).getMessageDao();
        Disposable subscribe = messageDao.insertAll(messages)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(() -> {
                    Log.d(TAG, "消息插入成功");

                }, throwable -> {
                    Log.d(TAG, "消息插入失败");
                });
    }

    @Override
    protected void setListener() {
        EventBus.getDefault().register(this);
    }

    /**
     * 收到消息
     *
     * @param chatMessage
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveMsg(ChatMessage chatMessage) {
        chatMessageList.add(chatMessage);
        refreshData();
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_send:
                String content = mEditText.getText().toString();
                if (content.length() <= 0) {
                    Util.showToast(mContext, "消息不能为空哟");
                    return;
                }

                //1.暂时将发送的消息加入消息列表，实际以发送成功为准（也就是服务器返回你发的消息时）
                ChatMessage chatMessage = new ChatMessage();
                chatMessage.setContent(content);
                chatMessage.setIsMeSend(1);
                chatMessage.setIsRead(1);
                chatMessage.setTime(System.currentTimeMillis() + "");
                chatMessageList.add(chatMessage);
                refreshData();
                mEditText.setText("");
                //2.发送
                ChatMsg chatMsg = new ChatMsg();
                chatMsg.setMsg(content);
                chatMsg.setMsgId("12341234");
                chatMsg.setReceiverId(mTalkerId);
                chatMsg.setSenderId(SharePreferenceUtils.getString("userId"));
                DataContent dataContent = new DataContent();
                dataContent.setAction(MsgActionEnum.CHAT.type);
                dataContent.setChatMsg(chatMsg);
                String msg = JSON.toJSONString(dataContent);
                EventBus.getDefault().post(msg);
                //3.插入到消息列表
                MessageDao messageDao = MyDataBase.getInstance(mActivity).getMessageDao();
                String userId = SharePreferenceUtils.getString("userId");
                Disposable subscribe = messageDao.insert(new Message(Util.nextShort(), userId, mTalkerId, content,
                        Util.getDateFormat()))
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(() -> {
                            Log.d(TAG, "消息插入成功");
                        }, throwable -> {
                            Log.d(TAG, "消息插入失败");
                        });

                break;
            default:
                break;
        }
    }

    /**
     * 有了新的消息,从新刷数据
     */
    private void refreshData() {
        listView.setSelection(chatMessageList.size());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}
